package com.helloworld.demo.atomic;



import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

public class HelloAtomic {

    //方案123
    //private static volatile int sum = 0;

    //方案4
    private static AtomicInteger sum = new AtomicInteger(0);

    private static Object objectLock = new Object();

    private static ReentrantLock lock = new ReentrantLock();

    private static CASLock casLock = new CASLock();

    public static void main(String[] args) {
        for(int i = 0;i < 10;i++){
            Thread thread = new Thread(() -> {
                /*for(int j = 0;j < 10000;j++){
                    sum++;
                }*/
                //方案1:弊端 会阻塞，会调用内核态park,unpark方法，会上下文切换，性能低，操作重
                /*synchronized(objectLock){
                    for(int j = 0;j < 10000;j++){
                        sum++;
                    }
                }*/
                //方案2：
                /*lock.lock();
                try {
                    for(int j = 0;j < 10000;j++){
                        sum++;
                    }
                }finally {
                    lock.unlock();
                }*/

                //方案3：自定义CAS
                /*for(;;){
                    if(casLock.getState() == 0 && casLock.cas()){
                        try{
                            for(int j = 0;j < 10000;j++){
                                sum++;
                            }
                            System.out.println(casLock.getState());
                        }finally {
                            casLock.setState(0);
                        }
                        break;
                    }
                }*/
                //方案4：
                for(int j = 0;j < 10000;j++){
                    //原子自增
                    sum.incrementAndGet();
                }
            });
            thread.start();
        }

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(sum);
    }
}
